package com.design.consumer.p02;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Storage {

	private final int MAX_SIZE = 100;

	private LinkedList<Object> list = new LinkedList<>();

	private final Lock lock = new ReentrantLock();

	/** 仓库满的条件变量 */
	private final Condition full = lock.newCondition();

	/** 仓库空的条件变量 */
	private final Condition empty = lock.newCondition();

	/**
	 * 生产num个产品
	 * 
	 * @param num
	 */
	public void produce(int num) {
		// 获得锁
		lock.lock();

		while (list.size() + num > MAX_SIZE) {
			System.out.println("要生产的产品数量:" + num + ",库存量:" + list.size() + ",不能执行生产任务");

			try {
				// 条件不满足，生产阻塞
				full.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}

		// 生产条件满足的情况下，生产num个产品
		for (int i = 0; i < num; i++) {
			list.add(new Object());
		}
		System.out.println("生产产品数量:" + num + ",库存量:" + list.size());

		// 唤醒其他所有线程
		full.signalAll();
		empty.signalAll();

		// 释放锁
		lock.unlock();
	}

	public void consume(int num) {
		// 获得锁
		lock.lock();

		// 库存量不足
		while (list.size() < num) {
			System.out.println("要消费的产品数量:" + num + ",库存量:" + list.size() + ",暂时不能消费");

			try {
				// 条件不满足，消费阻塞
				empty.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		// 消费条件满足，消费num个产品
		for (int i = 0; i < num; i++) {
			list.removeFirst();
		}

		System.out.println("已经消费产品数:" + num + ",库存量:" + list.size());
		full.signalAll();
		empty.signalAll();

		// 释放锁
		lock.unlock();
	}

}
